home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '98 presents:
-
- Mortal Kombat 4 - CD crack by Static Vengeance
-
- Requirements:
- Hex editor and full game install
- W32Dasm if you wish to follow along
-
- So you want to learn to crack CD checks, do you? Alright, let's look at one type of CD check
- that'll take some digging and some (did I say "some" read that as a "ton of") manual work. The reason
- I bring it up as some CD checks are a lot more work and not being the most fluent in X86 assembly
- language I did it the old fasion way. Brute force traking down with a little help from W32Dasm from
- RUSoft. Anyways, first things first... The usual aproch: disassemble the exe file with W32Dasm. Then
- look for the tell tale signs of copy protection. My favorite method is to go up to the menu and select
- "Refs" and the select "String data references" and look for things like "Please Insert the CD", the volume
- name of the CD, "C:\" or things like that. But with MK4 there are none of the common tell tale strings
- to double click on. So plan 2 involves looking for the KERNEL32 call "GetDriveTypeA". To find out if
- this call was used in the program check in the disassembled listing, you would see something like this:
-
- +++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++
-
- Import Module 001: KERNEL32.dll
- Addr:xxxxxxxx hint(xxxx) Name: ?????????????
- --- Many more calls listed ---
- Addr:000D3BBE hint(00DF) Name: GetDriveTypeA
- --- Many more calls listed ---
-
- Well, it is used so you'll need to use the text string search to find it in the disassebly code.
- after checking around and making an edit. I ran the game and realized I had eliminated the cut scenes
- and intros but NOT the copy protection. So this leaves the last choice and that is calls through WINMM.
- much like the KERNEL32.dll, the WINMM.dll would show up like this:
-
- Import Module 005: WINMM.dll
-
- Addr:000D410E hint(001A) Name: joyGetDevCapsA
- Addr:000D414C hint(0094) Name: timeEndPeriod
- Addr:000D413A hint(0093) Name: timeBeginPeriod
- Addr:000D412C hint(001E) Name: joyGetPosEx
- Addr:000D4120 hint(001D) Name: joyGetPos
- Addr:000D40FE hint(0017) Name: auxSetVolume
- Addr:000D40EE hint(0014) Name: auxGetNumDevs
- Addr:000D40DC hint(0012) Name: auxGetDevCapsA
- Addr:000D40CC hint(0015) Name: auxGetVolume
- Addr:000D40BE hint(0097) Name: timeGetTime
- Addr:000D40AC hint(0032) Name: mciSendCommandA
-
- It's the last call we are interested in, it's the mciSendCommandA call that is used to operate
- the CD for music. However if a status call comes back with an error, then there's no CD in the drive.
- The program can check the track length and other things that will tell the program that the original CD
- is present. So we need to do a text string search for "mciSendCommandA" Doing so, you'll end up at this
- section of code with the first sequence of your search word:
-
- * Referenced by a CALL at Addresses:
- |:004AC333 , :004AC385 , :004AC4B9 , :004AC51C , :004AC58C <-- 9 Sections of code to check
- |:004AC61F , :004AC73B , :004AC926 , :004C3EFE
- |
- :004AC2B0 A180185400 mov eax, dword ptr [00541880]
- :004AC2B5 83EC24 sub esp, 00000024
- :004AC2B8 85C0 test eax, eax
- :004AC2BA 56 push esi
-
- * Reference To: WINMM.mciSendCommandA, Ord:0032h <-- Text string that got us here
- |
- :004AC2BB 8B353C024D00 mov esi, dword ptr [004D023C]
- :004AC2C1 7531 jne 004AC2F4
- :004AC2C3 8D442414 lea eax, dword ptr [esp+14]
-
- * Possible StringData Ref from Data Obj ->"cdaudio" <-- Deals with the CD
- |
- :004AC2C7 C744241C84264F00 mov [esp+1C], 004F2684
- :004AC2CF 50 push eax
- :004AC2D0 6800210000 push 00002100
- :004AC2D5 6803080000 push 00000803
- :004AC2DA 6A00 push 00000000
- :004AC2DC FFD6 call esi
- :004AC2DE F7D8 neg eax
- :004AC2E0 1BC0 sbb eax, eax
- :004AC2E2 40 inc eax
- :004AC2E3 A380185400 mov dword ptr [00541880], eax
- :004AC2E8 743F je 004AC329
- :004AC2EA 8B4C2418 mov ecx, dword ptr [esp+18]
- :004AC2EE 890D60185400 mov dword ptr [00541860], ecx
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004AC2C1(C)
- |
- :004AC2F4 A160185400 mov eax, dword ptr [00541860]
- :004AC2F9 8D542404 lea edx, dword ptr [esp+04]
- :004AC2FD 52 push edx
- :004AC2FE 6800010000 push 00000100
- :004AC303 6814080000 push 00000814
- :004AC308 50 push eax
- :004AC309 C744241C05000000 mov [esp+1C], 00000005
- :004AC311 FFD6 call esi
- :004AC313 85C0 test eax, eax
- :004AC315 7512 jne 004AC329
- :004AC317 8B442408 mov eax, dword ptr [esp+08]
- :004AC31B 85C0 test eax, eax
- :004AC31D 740A je 004AC329 <-- Zero here means error on command
- :004AC31F B801000000 mov eax, 00000001 <-- Otherwise a non-zero is saved in
- :004AC324 5E pop esi <-- in eax for a "good" result
- :004AC325 83C424 add esp, 00000024
- :004AC328 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004AC2E8(C), :004AC315(C), :004AC31D(C)
- |
- :004AC329 33C0 xor eax, eax <-- Redundant, but make sure eax = zero
- :004AC32B 5E pop esi
- :004AC32C 83C424 add esp, 00000024
- :004AC32F C3 ret
-
- Just to test to make sure this bit of code is used for the CD check I changed the loading
- of eax with 00000001 to mov eax, 00000000 which forces an error. Then I ran the game with the CD
- in my CD rom drive to test the results. Sure enough the game came up and asks for the original
- CD! So now we need to narrow it down and the elimenate the CD check totally. So checking through
- the first call resulted in nothing useful. So I checked into the second call and found this:
-
- * Referenced by a CALL at Address:
- |:004C3F1B <-- Where it was called from
- |
- :004AC380 83EC1C sub esp, 0000001C
- :004AC383 56 push esi
- :004AC384 57 push edi
- :004AC385 E826FFFFFF call 004AC2B0
- :004AC38A 85C0 test eax, eax
- :004AC38C 0F84A3000000 je 004AC435
- :004AC392 8B0D60185400 mov ecx, dword ptr [00541860]
- :004AC398 8B7C2428 mov edi, dword ptr [esp+28]
-
- * Reference To: WINMM.mciSendCommandA, Ord:0032h <-- Another WINMM call
- |
- :004AC39C 8B353C024D00 mov esi, dword ptr [004D023C]
- :004AC3A2 8D442414 lea eax, dword ptr [esp+14]
- :004AC3A6 50 push eax
- :004AC3A7 6810010000 push 00000110
- :004AC3AC 6814080000 push 00000814
- :004AC3B1 51 push ecx
- :004AC3B2 C744242C01400000 mov [esp+2C], 00004001
- :004AC3BA 897C2430 mov dword ptr [esp+30], edi
- :004AC3BE FFD6 call esi
- :004AC3C0 85C0 test eax, eax
- :004AC3C2 7571 jne 004AC435
- :004AC3C4 817C241840040000 cmp dword ptr [esp+18], 00000440
- :004AC3CC 7567 jne 004AC435
- :004AC3CE A160185400 mov eax, dword ptr [00541860]
- :004AC3D3 8D542408 lea edx, dword ptr [esp+08]
- :004AC3D7 52 push edx
- :004AC3D8 6800040000 push 00000400
- :004AC3DD 680D080000 push 0000080D
- :004AC3E2 50 push eax
- :004AC3E3 C744241C02000000 mov [esp+1C], 00000002
- :004AC3EB FFD6 call esi
- :004AC3ED 8B1560185400 mov edx, dword ptr [00541860]
- :004AC3F3 8D4C2414 lea ecx, dword ptr [esp+14]
- :004AC3F7 51 push ecx
- :004AC3F8 6810010000 push 00000110
- :004AC3FD 6814080000 push 00000814
- :004AC402 52 push edx
- :004AC403 C744242C01000000 mov [esp+2C], 00000001
- :004AC40B 897C2430 mov dword ptr [esp+30], edi
- :004AC40F FFD6 call esi
- :004AC411 85C0 test eax, eax
- :004AC413 7520 jne 004AC435
- :004AC415 8B442418 mov eax, dword ptr [esp+18]
- :004AC419 33C9 xor ecx, ecx
- :004AC41B 8ACC mov cl, ah
- :004AC41D 25FF000000 and eax, 000000FF
- :004AC422 8D0440 lea eax, dword ptr [eax+2*eax]
- :004AC425 8D1480 lea edx, dword ptr [eax+4*eax]
- :004AC428 C1E202 shl edx, 02
- :004AC42B 03CA add ecx, edx
- :004AC42D 8BC1 mov eax, ecx
- :004AC42F 5F pop edi
- :004AC430 5E pop esi
- :004AC431 83C41C add esp, 0000001C
- :004AC434 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004AC38C(C), :004AC3C2(C), :004AC3CC(C), :004AC413(C)
- |
- :004AC435 5F pop edi
- :004AC436 33C0 xor eax, eax
- :004AC438 5E pop esi
- :004AC439 83C41C add esp, 0000001C
- :004AC43C C3 ret
-
- So I started with an unmodified version of the MK4 exe file and changed the conditional
- jump at 4AC38C to normal jump. Then I reran the MK4 and it asked for the CD again so we now
- know we're on the right track. So lets trace this routine back to it's caller and check that
- code.
-
- * Referenced by a CALL at Addresses:
- |:004B1B78 , :004B8248
- |
- :004C3EA0 83EC3C sub esp, 0000003C
- :004C3EA3 56 push esi
- :004C3EA4 33C9 xor ecx, ecx <-- ecx is zero'ed out here
- :004C3EA6 B85C000000 mov eax, 0000005C
- :004C3EAB 57 push edi
- :004C3EAC 894C2408 mov dword ptr [esp+08], ecx <-- Set up many variables
- :004C3EB0 8944240C mov dword ptr [esp+0C], eax
- :004C3EB4 89442410 mov dword ptr [esp+10], eax
- :004C3EB8 89442414 mov dword ptr [esp+14], eax
- :004C3EBC 89442418 mov dword ptr [esp+18], eax
- :004C3EC0 8944241C mov dword ptr [esp+1C], eax
- :004C3EC4 89442420 mov dword ptr [esp+20], eax
- :004C3EC8 89442424 mov dword ptr [esp+24], eax
- :004C3ECC C74424287A000000 mov [esp+28], 0000007A
- :004C3ED4 C744242C10000000 mov [esp+2C], 00000010
- :004C3EDC C744243038000000 mov [esp+30], 00000038
- :004C3EE4 89442434 mov dword ptr [esp+34], eax
- :004C3EE8 89442438 mov dword ptr [esp+38], eax
- :004C3EEC 8944243C mov dword ptr [esp+3C], eax
- :004C3EF0 C74424405A000000 mov [esp+40], 0000005A
- :004C3EF8 890DFCDC4F00 mov dword ptr [004FDCFC], ecx <-- Store a zero here
- :004C3EFE E8AD83FEFF call 004AC2B0
- :004C3F03 85C0 test eax, eax
- :004C3F05 743E je 004C3F45
- :004C3F07 E82484FEFF call 004AC330
- :004C3F0C 83F80F cmp eax, 0000000F
- :004C3F0F 7534 jne 004C3F45
- :004C3F11 BE01000000 mov esi, 00000001
- :004C3F16 8D7C240C lea edi, dword ptr [esp+0C]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004C3F39(C)
- |
- :004C3F1A 56 push esi
- :004C3F1B E86084FEFF call 004AC380 <-- Call the above CD audio check
- :004C3F20 8B57FC mov edx, dword ptr [edi-04]
- :004C3F23 83C404 add esp, 00000004
- :004C3F26 2BC2 sub eax, edx
- :004C3F28 99 cdq
- :004C3F29 33C2 xor eax, edx
- :004C3F2B 2BC2 sub eax, edx
- :004C3F2D 83F805 cmp eax, 00000005
- :004C3F30 7F13 jg 004C3F45
- :004C3F32 46 inc esi
- :004C3F33 83C704 add edi, 00000004
- :004C3F36 83FE0F cmp esi, 0000000F
- :004C3F39 7EDF jle 004C3F1A <-- Compare and the possibly jump
- :004C3F3B C705FCDC4F0001000000 mov dword ptr [004FDCFC], 00000001 <-- Store a 01 when it was initialized
- <-- with a 00, could be some type of
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: <-- flag variable used later
- |:004C3F05(C), :004C3F0F(C), :004C3F30(C)
- |
- :004C3F45 5F pop edi
- :004C3F46 5E pop esi
- :004C3F47 83C43C add esp, 0000003C
- :004C3F4A C3 ret
-
- In my work cracking CD checks, I have come to notice things like clearing a location then
- further down in the code setting it to a different value right after a condition jump. More times
- then not this is setting a "flag" to a fail value, making the test for the CD then if the test passes
- set the flag to a "pass" value. Okay, let's go back one more step and look at that code:
-
- :004B1B6E E89DE1F6FF call 0041FD10
- :004B1B73 E8A82CFBFF call 00464820
- :004B1B78 E823230100 call 004C3EA0 <-- Call the routine to check for the CD
- :004B1B7D A1FCDC4F00 mov eax, dword ptr [004FDCFC] <-- Check the "flag" value
- :004B1B82 85C0 test eax, eax
- :004B1B84 750A jne 004B1B90 <-- Anything but 01 passes
- :004B1B86 6A07 push 00000007
- :004B1B88 E8B33B0000 call 004B5740 <-- Do the sword sound & ask for the CD
- :004B1B8D 83C404 add esp, 00000004
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B1B84(C)
- |
- :004B1B90 C3 ret
-
- Okay, from here I started with a clean (unmodified) copy of the MK4 exe and NOP'ed the
- conditional jump at 4B1B84 and ran the game with the CD in the drive. Sure enough I head the
- "double sword slash" sound and it asked for the CD. So we know the CD check is at 4C3EA0 and
- is called from 4B1B78 and 4B8248. From here, search the MK4 exe file for E8 23 23 01 00 and
- overwite it with B8 01 00 00 00 (mov eax, 00000001). Then search for the other call to the CD
- check (E8 53 BC 00 00) and do the same. You'll have a cracked copy of Mortal Kombat 4 you can
- play from your hard drive.
-
- Midway released an updated version of Mortal Kombat 4 that has better support for Win98
- and DirectX6 (which means they fixxed some program BUGS). So I downloaded that file and did
- the same type of thing as I did above and found the two calls the CD check. I made the same
- type of patches:
-
- :004B2618 E8F3D6F6FF call 0041FD10
- :004B261D E80E22FBFF call 00464830
- :004B2622 E8C92B0100 call 004C51F0 <-- Do the CD check
- :004B2627 39357CFD4F00 cmp dword ptr [004FFD7C], esi <-- Test the flag, esi=00
- :004B262D 750A jne 004B2639 <-- If not equal jump over asking for CD
- :004B262F 6A07 push 00000007
- :004B2631 E80A3D0000 call 004B6340 <-- Sword sounds & ask for the CD
- :004B2636 83C404 add esp, 00000004
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B262D(C)
- |
- :004B2639 893520F97A00 mov dword ptr [007AF920], esi
- :004B263F 89351CF97A00 mov dword ptr [007AF91C], esi <-- Zero out CRC flag
- :004B2645 E816A4FFFF call 004ACA60 <-- Remember this call for later!!!
- :004B264A 85C0 test eax, eax
- :004B264C 7430 je 004B267E
-
- * Reference To: WINMM.timeGetTime, Ord:0097h
- |
- :004B264E FF1540224D00 Call dword ptr [004D2240]
- :004B2654 50 push eax
- :004B2655 E8A63E0100 call 004C6500
- :004B265A 83C404 add esp, 00000004
- :004B265D E8AE3E0100 call 004C6510
- :004B2662 A803 test al, 03
- :004B2664 7409 je 004B266F
- :004B2666 893D20F97A00 mov dword ptr [007AF920], edi
- :004B266C 5F pop edi
- :004B266D 5E pop esi
- :004B266E C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B2664(C)
- |
- :004B266F E89C3E0100 call 004C6510
- :004B2674 0D81180000 or eax, 00001881 <-- OR the results with 00001881
- :004B2679 A31CF97A00 mov dword ptr [007AF91C], eax <-- 7AF91C must equal zero to play!
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B264C(C)
- |
- :004B267E 5F pop edi
- :004B267F 5E pop esi
- :004B2680 C3 ret
-
- It worked, sort of. You just cannot move left in any portion of the game, either with your
- fighter or on the menu selections. Well, there must be some type of secondary copy protection.
- So I checked the disassembley and found some "filler" bytes (IE: bytes used so routines start on
- even memory locations like 41FD10 istead of 41FD1x where x is 1 to 9), in this case 90's are used
- for the filler. So I picked one and changed it to a 91 and ran the game with the CD in the drive.
- The game started up like normal and didn't ask for the CD or anything funny, except I couldn't
- move left! So Midway has added a CRC (or some type of checksum) check to the game. Once again,
- back to some old fasion manual work to track it down. I have never had to track down a checksum
- check before so I had to find some where to start. I thought as long as the program had to run a
- checksum on itself it would need to read the exe file off the hard drive. And I know to do that
- you need to use the "rb" (read binary?) call. So I went up to the REFS menu and selected "String
- data references" and from the pop up box I scrolled down to "rb" and double clicked it and checked
- the code around it and I came across this:
-
- * Referenced by a CALL at Address:
- |:004ACA92 <-- Where it was called from
- |
- :004ACAE0 B810400000 mov eax, 00004010
- :004ACAE5 E8E6920100 call 004C5DD0
- :004ACAEA 8B842414400000 mov eax, dword ptr [esp+00004014]
- :004ACAF1 53 push ebx
- :004ACAF2 55 push ebp
- :004ACAF3 56 push esi
- :004ACAF4 57 push edi
-
- * Possible StringData Ref from Data Obj ->"rb" <-- what got use here, a "read binary" call
- |
- :004ACAF5 685C504D00 push 004D505C
- :004ACAFA 50 push eax
- :004ACAFB E8B0920100 call 004C5DB0
- :004ACB00 8BD8 mov ebx, eax
- :004ACB02 83C408 add esp, 00000008
- :004ACB05 85DB test ebx, ebx
- :004ACB07 7510 jne 004ACB19
- :004ACB09 B8FEFFFFFF mov eax, FFFFFFFE
- :004ACB0E 5F pop edi
- :004ACB0F 5E pop esi
- :004ACB10 5D pop ebp
- :004ACB11 5B pop ebx
- :004ACB12 81C410400000 add esp, 00004010
- :004ACB18 C3 ret
-
- From here we need to go back to the caller to see if it has anything to do with the copy
- protection. So let's check out the code and routine around 4ACA92 to see what it does:
-
- * Referenced by a CALL at Address:
- |:004B2645 <-- Where it was called from
- |
- :004ACA60 81EC00040000 sub esp, 00000400
- :004ACA66 8D442400 lea eax, dword ptr [esp]
- :004ACA6A 6800040000 push 00000400
- :004ACA6F 50 push eax
- :004ACA70 6A00 push 00000000
-
- * Reference To: KERNEL32.GetModuleHandleA, Ord:00FEh
- |
- :004ACA72 FF152C214D00 Call dword ptr [004D212C]
- :004ACA78 50 push eax
-
- * Reference To: KERNEL32.GetModuleFileNameA, Ord:00FCh <-- Checking name of the exe file?!?
- |
- :004ACA79 FF15A0204D00 Call dword ptr [004D20A0]
- :004ACA7F 85C0 test eax, eax
- :004ACA81 750A jne 004ACA8D
- :004ACA83 83C8FF or eax, FFFFFFFF
- :004ACA86 81C400040000 add esp, 00000400
- :004ACA8C C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACA81(C) <-- Conditional jump down to here
- |
- :004ACA8D 8D4C2400 lea ecx, dword ptr [esp]
- :004ACA91 51 push ecx
- :004ACA92 E849000000 call 004ACAE0 <-- The call to the "rb" call
- :004ACA97 83C404 add esp, 00000004
- :004ACA9A 85C0 test eax, eax
- :004ACA9C 752C jne 004ACACA
- :004ACA9E 8B1520395400 mov edx, dword ptr [00543920]
- :004ACAA4 A198464F00 mov eax, dword ptr [004F4698]
- :004ACAA9 3BD0 cmp edx, eax
- :004ACAAB 750F jne 004ACABC
- :004ACAAD A124395400 mov eax, dword ptr [00543924]
- :004ACAB2 8B0D9C464F00 mov ecx, dword ptr [004F469C]
- :004ACAB8 3BC1 cmp eax, ecx
- :004ACABA 740C je 004ACAC8
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACAAB(C)
- |
- :004ACABC B8F6FFFFFF mov eax, FFFFFFF6 <-- Multiple exits and exit values!
- :004ACAC1 81C400040000 add esp, 00000400
- :004ACAC7 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACABA(C)
- |
- :004ACAC8 33C0 xor eax, eax <-- Multiple exits and exit values!
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACA9C(C)
- |
- :004ACACA 81C400040000 add esp, 00000400
- :004ACAD0 C3
-
- To me, this section of code is looking good for being the culprit. It's doing some KERNEL32
- calls and getting the module file name. That sounds like it's getting the name the exe file that was
- run, right? So let's go back to the call at 4B2645 and check it out:
-
- :004B2618 E8F3D6F6FF call 0041FD10
- :004B261D E80E22FBFF call 00464830
- :004B2622 E8C92B0100 call 004C51F0 <-- Do the CD check
- :004B2627 39357CFD4F00 cmp dword ptr [004FFD7C], esi <-- Test the flag
- :004B262D 750A jne 004B2639 <-- If not equal jump over asking for CD
- :004B262F 6A07 push 00000007
- :004B2631 E80A3D0000 call 004B6340 <-- Sword sounds & ask for the CD
- :004B2636 83C404 add esp, 00000004
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B262D(C)
- |
- :004B2639 893520F97A00 mov dword ptr [007AF920], esi
- :004B263F 89351CF97A00 mov dword ptr [007AF91C], esi
- :004B2645 E816A4FFFF call 004ACA60 <-- Read the exe file!
- :004B264A 85C0 test eax, eax <-- Check the returned value
- :004B264C 7430 je 004B267E <-- Need to take this jump
-
- * Reference To: WINMM.timeGetTime, Ord:0097h
- |
- :004B264E FF1540224D00 Call dword ptr [004D2240]
- :004B2654 50 push eax
- :004B2655 E8A63E0100 call 004C6500
- :004B265A 83C404 add esp, 00000004
- :004B265D E8AE3E0100 call 004C6510
- :004B2662 A803 test al, 03
- :004B2664 7409 je 004B266F
- :004B2666 893D20F97A00 mov dword ptr [007AF920], edi
- :004B266C 5F pop edi
- :004B266D 5E pop esi
- :004B266E C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B2664(C)
- |
- :004B266F E89C3E0100 call 004C6510 <-- Do a checksum
- :004B2674 0D81180000 or eax, 00001881 <-- or the result with the actual checksum
- :004B2679 A31CF97A00 mov dword ptr [007AF91C], eax <-- store it here
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004B264C(C)
- |
- :004B267E 5F pop edi
- :004B267F 5E pop esi
- :004B2680 C3 ret
-
- Well we ended up right back to the code that checks for the CD! Then the above routine
- does a checksum on the exe to see if we tried to crack it. So, the only thing left to do with
- this newly updated MK4 off the net is to make the actual edits to the Mortal Kombat 4.exe file.
- As you already know changing the two calls to the CD check with mov eax, 00000001 FiX'es the
- actual check. However with the checksumming code I changed the first call (call 004ACA60) to
- xor eax, eax and filled in the rest with NOP's. This efectivly forces the je jump at 4B264C to
- always be taken which allows you to play a fully functional game of MK4 without the CD. Follow
- these steps to produce a cracked copy of MK4 (by version):
-
- 1. Do a normal install of the game (2 files copied)
- 2. Copy all files from the "DATA" directory from the MK4 CD
- into the same place you installed MK4 (except mk4.exe)
- 3. Edit Mortal Kombat 4.exe
- ==============================================
- Search for: E8 23 23 01 00 at offset 724,856
- Change to : B8 01 00 00 00
-
- Search for: E8 53 BC 00 00 at offset 751,176
- Change to : B8 01 00 00 00
-
- Edit Mortal Kombat 4.exe from mk4patch1.zip off the net
- ==============================================
- Search for: E8 C9 2B 01 00 at offset 727,586
- Change to : B8 01 00 00 00
-
- Search for: E8 16 A4 FF FF at offset 727,621
- Change to : 33 C0 90 90 90
-
- Search for: E8 83 C3 00 00 at offset 754,280
- Change to : B8 01 00 00 00
-
- Edit Mortal Kombat 4.exe from mk4patch3.zip off the net
- ==============================================
- Search for: E8 C9 2B 01 00 at offset 727,650
- Change to : B8 01 00 00 00
-
- Search for: E8 D6 A3 FF FF at offset 727,685
- Change to : 33 C0 90 90 90
-
- Search for: E8 83 C3 00 00 at offset 754,344
- Change to : B8 01 00 00 00
-
-
- That's it, after copying the files and making the above edit you'll have a copy of Mortal
- Kombat 4 that runs off your hard drive and you don't have to dig out the original MK4 CD to play
- it. Becuase this one has been FiX'ed
-
- Static Vengeance
-
- NOTE: When the game installs, it copies MK4.EXE off the CD and renames it to Mortal Kombat 4.exe
- therefore you do not need it to run the game as it is already there... just renamed.
-
- NOTE2: The URL for the MK4 patch is: http://www.midway.com/home/mk4/mk4patch3.zip
-